package com.kate.cloud.shiro.config;



import com.kate.cloud.shiro.entity.JzShiro;
import com.kate.cloud.shiro.filter.FormAuthenticationFilter;
import com.kate.cloud.shiro.filter.LogoutFilter;
import com.kate.cloud.shiro.filter.PermissionsAuthorizationFilter;
import com.kate.cloud.shiro.filter.RolesAuthorizationFilter;
import com.kate.cloud.shiro.realm.AuthorizeRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Configuration
public class ShiroConfig {

    /**
     * Form登录过滤器
     */
    private FormAuthenticationFilter shiroAuthcFilter() {
        FormAuthenticationFilter bean = new FormAuthenticationFilter();
        return bean;
    }

    /**
     * 登出过滤器
     */
    private LogoutFilter shiroLogoutFilter() {
        return new LogoutFilter();
    }

    /**
     * 权限字符串过滤器
     */
    private PermissionsAuthorizationFilter shiroPermsFilter() {
        return new PermissionsAuthorizationFilter();
    }

    /**
     * 角色权限过滤器
     */
    private RolesAuthorizationFilter shiroRolesFilter() {
        return new RolesAuthorizationFilter();
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean(name = "hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }

    @Bean(name = "authorizeRealm")
    @DependsOn("lifecycleBeanPostProcessor")
    public AuthorizeRealm authorizeRealm() {
        AuthorizeRealm authorizeRealm = new AuthorizeRealm();
        authorizeRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return authorizeRealm;
    }

    @Bean
    public EhCacheManager ehCacheManager(){
        System.out.println("ShiroConfiguration.getEhCacheManager()");
        EhCacheManager cacheManager = new EhCacheManager();
        cacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
        return cacheManager;
    }


    @Bean(name = "securityManager")
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(authorizeRealm());
        securityManager.setRememberMeManager(rememberMeManager());
        securityManager.setCacheManager(ehCacheManager());
        return securityManager;
    }

    @Bean
    public JzShiro jzShiro(){
        return new JzShiro();
    }

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
        filters.put("authc", shiroAuthcFilter());
        filters.put("logout", shiroLogoutFilter());
        filters.put("perms", shiroPermsFilter());
        filters.put("roles", shiroRolesFilter());
        List<String> list = jzShiro().getList();
        Map<String, String> filterChainDefinitionManager = list.stream().collect(Collectors.toMap(x -> x.split("=")[0],
                x -> x.split("=")[1],(key1, key2) -> key2,LinkedHashMap::new));
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
        //shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        return shiroFilterFactoryBean;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();
        aASA.setSecurityManager(securityManager());
        return aASA;
    }


    public SimpleCookie rememberMeCookie(){
        System.out.println("cookie11111");
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        simpleCookie.setMaxAge(2592000);
        return simpleCookie;
    }

    public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
        return cookieRememberMeManager;
    }

}
